package lexico;

import java.io.*;
import lexico.Token;

public class Analisador {
	
	public static String Programa;
	static int menor = 0;
	static int maior = 1;
    static int linha = 1;
    
    public static void setPrograma(String programa) {
    	Programa = programa;
    }
    
 	public static Token nextToken() {
 		
 		Token token = new Token();
 		
		
 		/*// abertura do arquivo de entrada - ainda esta abrindo a cada chamada do token
 		String programa = "";
		
		try{
			  FileInputStream fstream = new FileInputStream("C:\\Users\\Tulio Duarte\\Desktop\\Compiladores 2\\Entrada\\palavras_simbolos_reservados1.txt");
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
			  while ((strLine = br.readLine()) != null)   {
				  programa = programa + strLine + "\n";
			  }
			  in.close();
			  } catch (Exception e){
				  System.err.println("Error: " + e.getMessage());
			  }
		
		Programa = programa;*/
		
		String caracter = "";
		String categoria = "";
	    String sequencia = "";

		
		caracter = Programa.substring(menor,maior);
		
		if (maior < Programa.length()) {
			
			// identifica espaco em branco e tabulacao
			while (caracter.equals(" ") || caracter.equals("\t")) {
				menor++; maior++;
				caracter = Programa.substring(menor,maior);
			}
			
			//identifica mudanca de linha
			if (caracter.equals("\n")) {
				menor++; maior++;
				linha++;
				return null;
			}
			
			//identifica cadeia de caracteres
			if (caracter.equals("\"")) {
				sequencia = sequencia + caracter;
				menor++; maior++;
				caracter = Programa.substring(menor,maior);
				while (!caracter.equals("\"")) {
					sequencia = sequencia + caracter;
					menor++; maior++;
					caracter = Programa.substring(menor,maior);
				}
				sequencia = sequencia + caracter;
				menor++; maior++;
				categoria = "";
				
				token.categoria = "CADEIA";
				token.sequencia = sequencia;
				token.linha = linha;
				
				System.out.println(sequencia + " - " + categoria);
				return token;
			}
			
			//identifica comentario
			if (caracter.equals("{")) {
				sequencia = sequencia + caracter;
				menor++; maior++;
				caracter = Programa.substring(menor,maior);
				while (!caracter.equals("}")) {
					sequencia = sequencia + caracter;
					menor++; maior++;
					caracter = Programa.substring(menor,maior);
				}
				sequencia = sequencia + caracter;
				menor++; maior++;
				
				token.categoria = "comentario";
				token.sequencia = sequencia;
				token.linha = linha;
				
				//System.out.println(sequencia + " - " + categoria);
				return nextToken();
			}
			
			//identifica numeros inteiros e numeros reais
			if (caracter.equals("0") || caracter.equals("1") ||caracter.equals("2") ||caracter.equals("3") ||caracter.equals("4") ||caracter.equals("5") ||caracter.equals("6") ||caracter.equals("7") ||caracter.equals("8") ||caracter.equals("9")) {
				sequencia = sequencia + caracter;
				menor++; maior++;
				caracter = Programa.substring(menor,maior);
				while (caracter.equals("0") || caracter.equals("1") ||caracter.equals("2") ||caracter.equals("3") ||caracter.equals("4") ||caracter.equals("5") ||caracter.equals("6") ||caracter.equals("7") ||caracter.equals("8") ||caracter.equals("9")) {
					sequencia = sequencia + caracter;
					menor++; maior++;
					caracter = Programa.substring(menor,maior);
				}
				if (caracter.equals(".")) {
					if (!Programa.substring(menor+1,maior+1).equals("0") && !Programa.substring(menor+1,maior+1).equals("1") && !Programa.substring(menor+1,maior+1).equals("2") && !Programa.substring(menor+1,maior+1).equals("3") && !Programa.substring(menor+1,maior+1).equals("4") && !Programa.substring(menor+1,maior+1).equals("5") && !Programa.substring(menor+1,maior+1).equals("6") && !Programa.substring(menor+1,maior+1).equals("7") && !Programa.substring(menor+1,maior+1).equals("8") && !Programa.substring(menor+1,maior+1).equals("9")){
						categoria = "NUM_INT";
						
						token.categoria = "NUM_INT";
						token.sequencia = sequencia;
						token.linha = linha;
						
						System.out.println(sequencia + " - " + categoria);
						return token;
					}
					sequencia = sequencia + caracter;
					menor++; maior++;
					caracter = Programa.substring(menor,maior);
					while (caracter.equals("0") || caracter.equals("1") ||caracter.equals("2") ||caracter.equals("3") ||caracter.equals("4") ||caracter.equals("5") ||caracter.equals("6") ||caracter.equals("7") ||caracter.equals("8") ||caracter.equals("9")) {
						sequencia = sequencia + caracter;
						menor++; maior++;
						caracter = Programa.substring(menor,maior);
					}
					//menor++; maior++;
					categoria = "NUM_REAL";
					
					token.categoria = "NUM_REAL";
					token.sequencia = sequencia;
					token.linha = linha;
					
					System.out.println(sequencia + " - " + categoria);
					return token;
					
				}
				else {
					menor++; maior++;
					categoria = "NUM_INT";
					
					token.categoria = "NUM_INT";
					token.sequencia = sequencia;
					token.linha = linha;
					
					System.out.println(sequencia + " - " + categoria);
					return token;
				}
			}
			
			//identifica IDENT e palavras reservadas
			char c = Programa.charAt(menor);
		    int j = (int) c;
		    //System.out.println(j);
			if ((j >= 65 && j <= 90) || (j >= 97 && j <= 122) || (j == 95)) {
				sequencia = sequencia + caracter;
				menor++; maior++;
				caracter = Programa.substring(menor,maior);
				c = caracter.charAt(0);
			    j = (int) c;
				while ((j >= 65 && j <= 90) || (j >= 97 && j <= 122) || (j == 95) || (j >= 48 && j <= 57)) {
					
					sequencia = sequencia + caracter;
					menor++; maior++;
					caracter = Programa.substring(menor,maior);
					c = caracter.charAt(0);
				    j = (int) c;
				}
				//menor++; maior++;
					if (palavras_reservadas(sequencia)) {
						categoria = sequencia;
						
						token.categoria = sequencia;
						token.sequencia = sequencia;
						token.linha = linha;
						
						System.out.println(sequencia + " - " + categoria);
						return token;
					}
				categoria = "IDENT";
				
				token.categoria = "IDENT";
				token.sequencia = sequencia;
				token.linha = linha;
				
				System.out.println(sequencia + " - " + categoria);
				return token;
			}
			
			// identifica simbolos reservados simples e duplos
			if (caracter.equals(":") || caracter.equals(",") || caracter.equals("^") || caracter.equals("(") || caracter.equals(")") || caracter.equals("-") || caracter.equals("%") || caracter.equals("*") || caracter.equals("/") || caracter.equals("+") || caracter.equals("&") || caracter.equals("=") || caracter.equals("<") || caracter.equals(">") || caracter.equals(".") || caracter.equals("[") || caracter.equals("]")) {
				sequencia = sequencia + caracter;
				menor++; maior++;
				
				if (caracter.equals("<")) {
					caracter = Programa.substring(menor,maior);
					if (caracter.equals("-") || caracter.equals(">") || caracter.equals("=")) {
						sequencia = sequencia + caracter;
						categoria = "simbolo_reservado";
						menor++; maior++;
						
						token.categoria = sequencia;
						token.sequencia = sequencia;
						token.linha = linha;
						
						System.out.println(sequencia + " - " + sequencia);
						return token;
					}
				}
				if (caracter.equals(">")) {
					caracter = Programa.substring(menor,maior);
					if (caracter.equals("=")) {
						sequencia = sequencia + caracter;
						categoria = "simbolo_reservado";
						menor++; maior++;
						
						token.categoria = sequencia;
						token.sequencia = sequencia;
						token.linha = linha;
						
						System.out.println(sequencia + " - " + sequencia);
						return token;
					}
				}
				if (caracter.equals(".")) {
					caracter = Programa.substring(menor,maior);
					if (caracter.equals(".")) {
						sequencia = sequencia + caracter;
						categoria = "simbolo_reservado";
						menor++; maior++;
						
						token.categoria = sequencia;
						token.sequencia = sequencia;
						token.linha = linha;
						
						System.out.println(sequencia + " - " + sequencia);
						return token;
					}
				}
				
				categoria = "simbolo_reservado";
				
				token.categoria = sequencia;
				token.sequencia = sequencia;
				token.linha = linha;
				
				System.out.println(sequencia + " - " + sequencia);
				return token;
			}		
			
		}
		return null;
	}
 	
 	public static boolean palavras_reservadas(String token) {
 		
 		if (token.equals("algoritmo") || token.equals("fim_algoritmo") ||
 				token.equals("declare") || token.equals("literal") || token.equals("inteiro") ||
 				token.equals("real") || token.equals("logico") || token.equals("leia") ||
 				token.equals("escreva") || token.equals("se") || token.equals("entao") ||
 				token.equals("senao") || token.equals("fim_se") || token.equals("caso") ||
 				token.equals("seja") || token.equals("fim_caso") || token.equals("tipo") ||
 				token.equals("para") || token.equals("ate") || token.equals("faca") ||
 				token.equals("fim_para") || token.equals("enquanto") || token.equals("fim_enquanto") ||
 				token.equals("procedimento") || token.equals("fim_procedimento") ||
 				token.equals("funcao") || token.equals("fim_funcao") || token.equals("ou") ||
 				token.equals("e") || token.equals("nao") || token.equals("registro") ||
 				token.equals("fim_registro") || token.equals("var") || token.equals("constante") ||
 				token.equals("verdadeiro") || token.equals("falso") || token.equals("retorne")) {
 			return true;
 		}
 		return false;
 	}
	
	public static void main(String[] args) {
		
		// abertura do arquivo de entrada - ainda esta abrindo a cada chamada do token
 		String programa = "";
		
		try{
			  FileInputStream fstream = new FileInputStream("C:\\Users\\Tulio Duarte\\Desktop\\Compiladores 2\\Entrada\\palavras_simbolos_reservados1.txt");
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
			  while ((strLine = br.readLine()) != null)   {
				  programa = programa + strLine + "\n";
			  }
			  in.close();
			  } catch (Exception e){
				  System.err.println("Error: " + e.getMessage());
			  }
			  
		  setPrograma(programa);
		
		  while (true) { nextToken();}
	}
}
